package com.csdj.t309.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.log4j.Logger;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.params.SetParams;

import javax.annotation.PostConstruct;

@Service
public class RedisService {

    private JedisPool pool = null;
    @Value("${redis.host:localhost}")
    private String host;
    @Value("${redis.port:6379}")
    private int port;
    @Value("${redis.password:123456}")
    private String password;

    private Logger log = Logger.getLogger("redisserver");

    @PostConstruct
    public void init(){
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMinIdle(2);
        config.setMaxTotal(20);
        pool = new JedisPool(config,host,port,3000,password);
    }

    public String getString(String key){
        Jedis resource = pool.getResource();
        try{
            if(resource != null){
                return resource.get(key);
            }
            return null;
        }finally {
            if(resource != null){
                resource.close();
            }
        }
    }

    /**
     *
     * @param key
     * @param object
     * @param sec 缓存时间
     * @return
     */
    public boolean setObj(String key ,Object object,int sec){
        Jedis resource = pool.getResource();
        try{
            if(resource != null){
                //jackson json转换器
                ObjectMapper om = new ObjectMapper();
                SetParams setParams = new SetParams();
                setParams.ex(sec);
                String res =  resource.set(key,om.writeValueAsString(object),setParams);
                if("OK".equalsIgnoreCase(res)){
                    return true;
                }
            }
            return false;
        } catch (JsonProcessingException e) {
            log.error(e.getClass(),e);
            return false;
        } finally {
            if(resource != null){
                resource.close();
            }
        }
    }

    public <T> T getObj(String key,Class<T> clazz){
        Jedis resource = pool.getResource();
        try{
            if(resource != null){
                String res = resource.get(key);
                //判断是不否为空
                if(StringUtils.hasText(res)){
                    ObjectMapper om = new ObjectMapper();
                    return om.readValue(res,clazz);
                }
            }
            return null;
        } catch (JsonMappingException e) {
            log.error(e.getClass(),e);
            return null;
        } catch (JsonProcessingException e) {
            log.error(e.getClass(),e);
            return null;
        } finally {
            if(resource != null){
                resource.close();
            }
        }
    }

    /**
     * 订阅一个消息频道
     * @param channel
     * @param task
     */
    public void subscribe(String channel, JedisPubSub task){
        Jedis resource = pool.getResource();
        new Thread(()->{
            if(resource != null){
                resource.subscribe(task,channel);
            }
        }).start();
    }

    /**
     * 向频道中发布消息
     * @param channel
     * @param msg
     * @return
     */
    public boolean publish(String channel,String msg){
        Jedis resource = pool.getResource();
        try{
            if(resource != null){
                return resource.publish(channel,msg)>0;
            }
            return false;
        }finally {
            if(resource != null){
                resource.close();
            }
        }
    }
}
